package com.dream.technology.service.impl;

import com.dream.technology.components.riskControl.SymbolAnalysis;
import com.dream.technology.components.riskControl.SymbolConstan;
import com.dream.technology.components.riskControl.tianji.RcConstan;
import com.dream.technology.db.dao.*;
import com.dream.technology.db.entity.*;
import com.dream.technology.db.entity.vo.VoFlow;
import com.dream.technology.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service("rcFlowService")
public class RcFlowServiceImpl implements RcFlowService {
    private static final Logger logger = LoggerFactory.getLogger(RcRuleCollectionService.class);

    @Autowired
    RcFlowMapper rcFlowMapper;
    @Autowired
    RcFlowItemMapper rcFlowItemMapper;
    @Autowired
    RcFlowItemService flowItemService;
    @Autowired
    RcCustomerTagMapper rcCustomerTagMapper;
    @Autowired
    RcRuleCollectionMapper rcRuleCollectionMapper;
    /*@Autowired
    private AdminClient adminClient;
    @Autowired
    private ApiClient apiClient;*/

    @Autowired
    RcRuleMapper rcRuleMapper;
    @Autowired
    SymbolAnalysis symbolAnalysis;
    @Autowired
    private RcCustomerTagService tagService;
    @Autowired
    private RcRuleService ruleService;
    @Autowired
    private RcRuleCollectionService collectionService;

    @Override
    public int countByExample(RcFlowQuery example) {
        return rcFlowMapper.countByExample(example);
    }

    @Override
    @Transactional
    public int deleteByExample(RcFlowQuery example) {
        return rcFlowMapper.deleteByExample(example);
    }

    @Override
    @Transactional
    public int deleteByPrimaryKey(Long id) {
        return rcFlowMapper.deleteByPrimaryKey(id);
    }

    @Override
    @Transactional
    public int insert(RcFlow record) {
        return rcFlowMapper.insert(record);
    }

    @Override
    @Transactional
    public int add(RcFlow record) {
        //获取管理员id
        /*enericRspDTO<OperationAdmin> userInfo = adminClient.getUserInfoByToken();
        record.setAdminId(Long.valueOf(userInfo.getBody().getId()));
        record.setCreator(userInfo.getBody().getUserName());
        record.setFlowCode(RandomCode.getRiskControlClaCode());*/
        //保存CustoemrTag
        return insert(record);
    }

    @Override
    @Transactional
    public String insertStr(VoFlow voFlow) {

        logger.debug("addCustomerTagSetting str ========{}", voFlow);


        //获取管理员id
       /* GenericRspDTO<OperationAdmin> userInfo = adminClient.getUserInfoByToken();
        Integer id = userInfo.getBody().getId();
        String userName = userInfo.getBody().getUserName();
        String riskControlClaCode = RandomCode.getRiskControlClaCode();*/

        RcFlow flow = voFlow.getRcFlow();
        List<RcFlowItem> items = voFlow.getRcFlowItem();
        /*flow.setAdminId(Long.valueOf(id));
        flow.setCreator(userName);
        String desc = checkFlow(voFlow);
        flow.setFlowRuleDesc(desc);
        flow.setFlowCode(riskControlClaCode);*/
        //保存CustoemrTag
        insert(flow);
        ArrayList<RcFlowItem> tagItems = new ArrayList<>();
        for (int i = 0; i < items.size(); i++) {
            // 重新映射 别名与描述
//            String jsonStr = ruleItemList.getString(i);
            RcFlowItem rcFlowItem = items.get(i);
            rcFlowItem.setFlowId(flow.getId());
            tagItems.add(rcFlowItem);
        }
        rcFlowItemMapper.insertList(tagItems);
        return "success";

    }

    @Override
    @Transactional
    public int insertSelective(RcFlow record) {
        return rcFlowMapper.insertSelective(record);
    }

    @Override
    public List<RcFlow> selectByExample(RcFlowQuery example) {
        return rcFlowMapper.selectByExample(example);
    }

    @Override
    @Transactional
    public RcFlow selectByPrimaryKey(Long id) {
        return rcFlowMapper.selectByPrimaryKey(id);
    }

    @Override
    @Transactional
    public int updateByExampleSelective(RcFlow record, RcFlowQuery example) {
        return rcFlowMapper.updateByExampleSelective(record, example);
    }

    @Override
    @Transactional
    public int updateByExample(RcFlow record, RcFlowQuery example) {
        return rcFlowMapper.updateByExample(record, example);
    }

    @Override
    @Transactional
    public int updateByPrimaryKeySelective(RcFlow record) {
        return rcFlowMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    @Transactional
    public int updateByPrimaryKey(RcFlow record) {
        return rcFlowMapper.updateByPrimaryKey(record);
    }

    /**
     * 输入 ale|cd&(jke|iuy)   返回 期数等于7 或期数等于14 且（性别等同于男）。。。。
     *
     * @param voFlow
     * @return
     */
    @Override
    public String checkFlow(VoFlow voFlow) {

        logger.debug("checkruleCollectionSetting str ========{}", voFlow);

        //规则items
        List<RcFlowItem> rcFlowItems = voFlow.getRcFlowItem();
        //规则集表达式
        RcFlow flow = voFlow.getRcFlow();
        Map<String, String> aliasMap = new HashMap<>(rcFlowItems.size() << 1);
        ArrayList<Long> ruleIds = new ArrayList<>();
        for (int i = 0; i < rcFlowItems.size(); i++) {
//

            RcFlowItem item = rcFlowItems.get(i);
            Integer childItemType = item.getChildItemType();
            Long childItemId = item.getChildItemId();
            String childAlias = item.getItemAlias();
            // 重新映射 别名与描述
            switch (childItemType.toString()) {
                case SymbolConstan.FLOW_ITEM_TYPE_TAG:
                    RcCustomerTag rcCustomerTag = rcCustomerTagMapper.selectByPrimaryKey(childItemId);
                    aliasMap.put(childAlias, rcCustomerTag.getTagName() + getActionAndStragevy(item));
                    break;
                case SymbolConstan.FLOW_ITEM_TYPE_RULE:
                    RcRule rcRule = rcRuleMapper.selectByPrimaryKey(childItemId);
                    aliasMap.put(childAlias, rcRule.getRuleName() + getActionAndStragevy(item));
                    break;
                case SymbolConstan.FLOW_ITEM_TYPE_COLL:
                    RcRuleCollection rcRuleCollection = rcRuleCollectionMapper.selectByPrimaryKey(childItemId);
                    aliasMap.put(childAlias, rcRuleCollection.getCollectionName() + getActionAndStragevy(item));
                    break;
                default:
                    ;
            }
        }
        return symbolAnalysis.getExp(flow.getFlowRule(), aliasMap);
    }


    public String getActionAndStragevy(RcFlowItem item) {

        String actionAndStragevy = "";

        Integer action = item.getAction();
        Integer strategy = item.getStrategy();
        if (item.getChildItemType() != 0) {
            switch (action) {
                case 0:
                    actionAndStragevy = " 拒绝 ";
                    break;
                case 1:
                    actionAndStragevy = " 通过 ";
                    break;
                default:
            }
        }
        switch (strategy) {
            case 0:
                actionAndStragevy += " 直接拒绝 ";
                break;
            case 1:
                actionAndStragevy += " 执行下一步 ";
                break;
            case 2:
                actionAndStragevy += " 通过进入审核 ";
                break;
            default:
        }
        return actionAndStragevy;
    }

    @Override
    public List<RcFlow> queryFlowByTag(int childItemType, Long customerTag) {
        return rcFlowMapper.queryFlowByTag(childItemType, customerTag);
    }


    /**
     * 复制流程
     *
     * @param id
     * @param flowName
     * @param flowDetail
     * @param enabled
     * @return
     */
    @Override
    @Transactional
    public String copy(Long id, String flowName, String flowDetail, Boolean enabled) {
        RcFlow flow = rcFlowMapper.selectByPrimaryKey(id);
//        flow.setFlowCode(RandomCode.getRiskControlClaCode());
        flow.setId(null);
        flow.setFlowName(flowName);
        flow.setFlowDetail(flowDetail);
        flow.setEnabled(enabled);
        flow.setCreateDate(new Date());
        insertSelective(flow);
        flowItemService.copy(id, flow.getId());
        return RcConstan.SUCCESS;
    }

    /**
     * 修改风控流程 包含流程配置项
     *
     * @param voFlow
     * @return
     */
    @Override
    @Transactional
    public String updateByJsonStr(VoFlow voFlow) {
        logger.debug("addCustomerTagSetting str ========{}", voFlow);

        RcFlow rcFlow = voFlow.getRcFlow();
        List<RcFlowItem> rcFlowItems = voFlow.getRcFlowItem();
        String desc = checkFlow(voFlow);
        rcFlow.setFlowRuleDesc(desc);
        updateByPrimaryKeySelective(rcFlow);

        List<RcFlowItem> oldItems = flowItemService.selectByFlowId(rcFlow.getId());
        ArrayList<Long> itemIds = new ArrayList<>();

        rcFlowItems.forEach(item -> {
            if (item.getId() != null) {
                flowItemService.updateByPrimaryKeySelective(item);
                itemIds.add(item.getId());
            } else {
                item.setFlowId(rcFlow.getId());
                item.setEnabled(true);
                item.setStatus(false);
                flowItemService.insertSelective(item);
            }
        });
        List<RcFlowItem> deleteItems = oldItems.stream().filter(item -> !itemIds.contains(item.getId())).collect(Collectors.toList());
        deleteItems.forEach(item -> flowItemService.deleteByPrimaryKey(item.getId()));

        return null;
    }

    /**
     * 查询流程子项中的元素
     *
     * @return
     */
    @Override
    public List<Long> getChildIdsByFlowId(Long id, String type) {

        RcFlowItemQuery query = new RcFlowItemQuery();
        RcFlowItemQuery.Criteria criteria = query.createCriteria();
        criteria.andFlowIdEqualTo(id);
        criteria.andChildItemTypeEqualTo(Integer.valueOf(type));
        List<RcFlowItem> rcFlowItems = flowItemService.selectByExample(query);

        ArrayList<Long> itemIds = new ArrayList<>();
        rcFlowItems.forEach(item -> itemIds.add(item.getId()));
        return itemIds;
    }


    /**
     * 查询流程子项中的用户标签
     *
     * @param id
     * @return
     */
    @Override
    public List<RcCustomerTag> getTagByFlowId(Long id) {

        List<Long> itemIds = getChildIdsByFlowId(id, SymbolConstan.FLOW_ITEM_TYPE_TAG);
        RcCustomerTagQuery customerTagQuery = new RcCustomerTagQuery();
        RcCustomerTagQuery.Criteria criteria1 = customerTagQuery.createCriteria();
        criteria1.andIdIn(itemIds);
        List<RcCustomerTag> rcCustomerTags = rcCustomerTagMapper.selectByExample(customerTagQuery);

        return rcCustomerTags;
    }

    /**
     * 查询子流程流程子项中的子项id
     *
     * @param ids
     * @param type
     * @return
     */
    @Override
    public List<Long> getChildIdsByFlowIds(List<Long> ids, String type) {
        RcFlowItemQuery query = new RcFlowItemQuery();
        RcFlowItemQuery.Criteria criteria = query.createCriteria();
        criteria.andFlowIdIn(ids);
        criteria.andChildItemTypeEqualTo(Integer.valueOf(type));
        List<RcFlowItem> rcFlowItems = flowItemService.selectByExample(query);

        ArrayList<Long> itemIds = new ArrayList<>();
        rcFlowItems.forEach(item -> itemIds.add(item.getId()));
        return itemIds;
    }

    /**
     * 查询流程子项中的规则
     *
     * @param id
     * @return
     */
    @Override
    public List<RcRule> getRuleByFlowId(Long id) {
        List<Long> itemIds = getChildIdsByFlowId(id, SymbolConstan.FLOW_ITEM_TYPE_RULE);
        RcRuleQuery query = new RcRuleQuery();
        RcRuleQuery.Criteria criteria = query.createCriteria();
        criteria.andIdIn(itemIds);
        List<RcRule> rcRules = rcRuleMapper.selectByExample(query);
        return rcRules;
    }




    /**
     * 查询流程子项中的规则集
     *
     * @param id
     * @return
     */
    @Override
    public List<RcRuleCollection> getRuleCollectionByFlowId(Long id) {
        List<Long> itemIds = getChildIdsByFlowId(id, SymbolConstan.FLOW_ITEM_TYPE_COLL);
        RcRuleCollectionQuery query = new RcRuleCollectionQuery();
        RcRuleCollectionQuery.Criteria criteria = query.createCriteria();
        criteria.andIdIn(itemIds);
        List<RcRuleCollection> rcRuleCollections = rcRuleCollectionMapper.selectByExample(query);
        return rcRuleCollections;
    }

    @Override
    public Map<String, Object> getAllChildItem(Integer childItemType) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (childItemType == 0) {
            // 查询用户标签
            RcCustomerTagQuery tagQuery = new RcCustomerTagQuery();
            RcCustomerTagQuery.Criteria criteriaTag = tagQuery.createCriteria();
            criteriaTag.andStatusEqualTo(false);
            criteriaTag.andEnabledEqualTo(true);
            map.put("list", tagService.selectByExample(tagQuery));
        }
        if (childItemType == 1) {
            // 查询规则
            RcRuleQuery ruleQuery = new RcRuleQuery();
            RcRuleQuery.Criteria criteriaRule = ruleQuery.createCriteria();
            criteriaRule.andStatusEqualTo(false);
            criteriaRule.andEnabledEqualTo(true);
            map.put("list", ruleService.selectByExample(ruleQuery));
        }
        if (childItemType == 2) {
            // 查询规则集
            RcRuleCollectionQuery collectionQuery = new RcRuleCollectionQuery();
            RcRuleCollectionQuery.Criteria criteriaCollection = collectionQuery.createCriteria();
            criteriaCollection.andStatusEqualTo(false);
            criteriaCollection.andEnabledEqualTo(true);
            map.put("list", collectionService.selectByExample(collectionQuery));
        }
        return map;
    }

    /**
     * 根据平台 ，模块名称 ，获取风控流程id
     *
     * @return
     */
    @Override
    public RcFlow getFlowByPlatform(String platform) {
//        GenericRspDTO<Object> windControlWithProductId = adminClient.getWindControlWithProductId(platform);
//        List<Long> body = (List<Long>) windControlWithProductId.getBody();
        RcFlowQuery query = new RcFlowQuery();
//        query.createCriteria().andIdIn(body);
        List<RcFlow> rcFlows = selectByExample(query);
        if (rcFlows.isEmpty()) {
            return null;
        } else {
            return rcFlows.get(0);
        }

    }

    /**
     * 根据平台 ，模块名称 ，获取风控流程id
     *
     * @return
     */
    @Override
    public RcFlow getFlowByPlatformApi(Long platform) {
//        GenericRspDTO<Object> windControlWithProductId = apiClient.getAppliedWindControls(platform);
//        JSONArray body = (JSONArray) windControlWithProductId.getBody();
//        List<Long> ids = new ArrayList<>(Arrays.asList(24L));// 测试
        RcFlowQuery query = new RcFlowQuery();
//         query.createCriteria().andIdIn(body);
//        Long valueId = body.getJSONObject(1).getLong("valueId");
//        query.createCriteria().andIdEqualTo(valueId);
        List<RcFlow> rcFlows = selectByExample(query);
        if (rcFlows.isEmpty()) {
            return null;
        } else {
            return rcFlows.get(0);
        }

    }


}
